#ifndef __LOGGER_H__
#define __LOGGER_H__
#include "common.h"
#include <iostream>
#include <sstream>
#include "exception.h"
enum LoggerLevel{
	PROFILE,
	DEBUG,
	INFO,
	WARN,
	ERROR,
	FATAL,
};
class Logger {
public:
	Logger(){
	}

	~Logger(){
		Output();
	}

	template< typename T > Logger& operator<<( T msg ){
		AppendMsg( msg );
		return *this;
	}

	Logger& operator<<( std::ostream& (*__pf)(std::ostream&) ){
		if( (std::ostream& (*)(std::ostream&))std::endl == __pf || 
	    	    (std::ostream& (*)(std::ostream&))std::flush == __pf){
			Output();
		}
		return *this;
	}
private:
	void Output(){
		if( !mLogMsg.empty() ){
			std::cout << mLogMsg<< std::endl;
			mLogMsg.clear();
		}
		return;
	}
	
	template<typename T> void AppendMsg( T msg ){
		std::ostringstream logStream;
		logStream << msg;
		mLogMsg += logStream.str();
		return;
	}

private:
	std::string mLogMsg;
};

#define LOG( ... )	\
	Logger() << "PID:" << getpid() << " ThreadId:" << pthread_self() << " File:" << __FILE__ << " Function:" << __func__ << " Line:" << __LINE__ << " -- " 

#define THROWLOG( LEVEL, PREFIX, ERRCODE, SUFFIX )			\
	LOG( LEVEL ) << PREFIX << Perror(ERRCODE) << ":" << SUFFIX << std::endl;	\
	THROW( ERRCODE, Perror(ERRCODE) )

void PrintLog( int32_t level, const std::string& key, const std::string& value ){
	LOG(level) << key << ":" << value << std::endl;
	return;
}

#endif

